import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # 去警告
import tensorflow as tf



# 准备真实数据：
# x：特征值，形状：（100,1）
# y_true：目标值 （100,1）
# y_true = 0.8x + 0.7 ，100个样本
# 假设满足： y =kx + b
#
# 分析：
#   由：[100,1] = [100,1] * [1,1]
#   得：y_predict = x * weights(1, 1) + bias(1,1)
# 1.构造模型
#   即：y_predict = tf.matul(x, weights) + bias(1,1)
# 2.构造损失函数
#      tf.reduce_mean( tf.square(y_predict - y_ture) )
# 3.优化损失（梯度下降优化器）
#      tf.train.GrandientDescentOptimizer(learning_rate=0.01)

def linear_refression():
    """
    自实现线性回归
    :return
    """
    # 1.准备数据
    X = tf.random.normal(shape=[100, 1])
    y_true = tf.matmul(X, [[0.8]]) + 0.7
    # 2.定义变量
    weights = tf.Variable(initial_value=tf.random.normal(shape=[1, 1]))
    bias = tf.Variable(initial_value=tf.random.normal(shape=[1, 1]))
    variables = [weights, bias]
    # 3.声明梯度下降优化算法
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

    # 实例化一个记录器
    log_dir = '../resources/p02_deep_learning_tensorFlow/tensorboard_out'
    summary_writer = tf.summary.create_file_writer(log_dir)  # 参数为记录文件所保存的目录
    # tf.summary.trace_on(profiler=True)  # 开启Trace（可选）：记录大量信息

    # 4.开始训练
    # 声明循环迭代次数
    num = 1000
    for s in range(num):
        with tf.GradientTape() as tape:
            y_predict = tf.matmul(X, weights) + bias  # 预测值
            loss = tf.reduce_mean(tf.square(y_predict - y_true))  # 损失函数(均方误差)
            grads = tape.gradient(loss, variables)  # 计算梯度
            optimizer.apply_gradients(grads_and_vars=zip(grads, variables))  # 更新参数（最小化某个特定的损失函数）

            # 通过 with 语句指定希望使用的记录器
            with summary_writer.as_default():  # 希望使用的记录器
                # 收集变量
                tf.summary.scalar("loss", loss, step=s)  # 收集标量

    # with summary_writer.as_default():
    #     tf.summary.trace_export(name="model_trace", step=0, profiler_outdir=log_dir) # 保存Trace信息到文件（可选）


    return None


if __name__ == '__main__':
    # 代码7：变量的演示
    linear_refression()
